package io.bsly.modules.platform.api.douDianApi;

import cn.hutool.json.JSONObject;
import io.bsly.common.utils.Constant;
import io.bsly.common.utils.HttpUtil;
import io.bsly.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 抖店工具类
 */
@Slf4j
@Component
public class DoudianHttpUtils {
    @Autowired
    private DouDianConfigVo douDianConfig;

    @Autowired
    public static DouDianConfigVo douDianBean;

    @Autowired
    private RedisTemplate redisTemplate;

    @PostConstruct
    public void init() {
        douDianBean = douDianConfig;
    }


    // 发送
    public  String send( String shopId ,String method,Map<String, Object> paraMap) throws IOException {
        long timestamp = System.currentTimeMillis() / 1000;
        String paramJson = DoudianBaseUtil.marshal(paraMap);
        String signVal = DoudianBaseUtil.sign(douDianBean.getAppKey(), douDianBean.getAppSecret(), method, timestamp, paramJson);
        // 发起请求
        String accessToken = doudianAccessToken(shopId);
        String responseVal = DoudianBaseUtil.fetch(douDianBean.getAppKey(), douDianBean.getHost(), method, timestamp, paramJson, accessToken, signVal);
        log.info("抖音平台返回 : {}  --  {} " ,method ,responseVal);
        return responseVal;
    }

    /**
     * https://openapi-fxg.jinritemai.com/token/create?app_key=your_app_key&method=token.create&param_json={"code":"","grant_type":"authorization_self","shop_id":"12312312"}&timestamp=2021-07-02 10:47:32&v=2&sign=your_sign_here
     * @param shopId
     * @return
     */
    public String doudianAccessToken(String shopId) throws IOException{
        if (redisTemplate.hasKey(Constant.DOUDIAN_ACCESS_TOKEN)){
            return (String) redisTemplate.opsForValue().get(Constant.DOUDIAN_ACCESS_TOKEN);
        }
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String date =   LocalDateTime.now().format(dtf) ;
        Map<String, Object> mapToken = new HashMap<>();
        mapToken.put("code", "");
        mapToken.put("grant_type", "authorization_self");
        mapToken.put("shop_id", shopId);
        String paramJson = DoudianBaseUtil.marshal(mapToken);
        String signVal = DoudianBaseUtil.sign(douDianBean.getAppKey(), douDianBean.getAppSecret(), "token.create", date, paramJson);
        String Url="https://openapi-fxg.jinritemai.com/token/create?app_key="+douDianBean.getAppKey()
                +"&method=token.create&param_json={\"code\":\"\",\"grant_type\":\"authorization_self\",\"shop_id\":\""+douDianBean.getShopId()+"\"}&timestamp="
                +date+"&v=2&sign="+signVal+"&sign_method=hmac-sha256";

        HttpUtil.ResponseData responStr = HttpUtil.get(Url,null);
        JSONObject responObject = new JSONObject(responStr.getData());
        if (responObject.containsKey("err_no") && "0".equals(responObject.get("err_no").toString())){
            AccessTokenVo tokenVo = responObject.get("data",AccessTokenVo.class);
            redisTemplate.opsForValue().set(Constant.DOUDIAN_ACCESS_TOKEN,tokenVo.getAccessToken(),tokenVo.getExpiresIn()-120, TimeUnit.SECONDS);
            redisTemplate.opsForValue().set(Constant.DOUDIAN_REFRESH_TOKEN,tokenVo.getRefreshToken(),tokenVo.getExpiresIn(), TimeUnit.SECONDS);
            return tokenVo.getAccessToken();
        }else{
            return null;
        }
    }

    /**
     * 老接口 --测试使用
     * @return
     */
    public String doudianToken(){
        if (redisTemplate.hasKey(Constant.DOUDIAN_ACCESS_TOKEN)){
            return (String) redisTemplate.opsForValue().get(Constant.DOUDIAN_ACCESS_TOKEN);
        }
        String url ="https://openapi-fxg.jinritemai.com/oauth2/access_token?app_id=%s&app_secret=%s&grant_type=authorization_self&shop_id=%s";
        url=String.format(url, douDianBean.getAppKey(),douDianBean.getAppSecret(),douDianBean.getShopId());
        HttpUtil.ResponseData responStr = HttpUtil.get(url,null);
        JSONObject responObject = new JSONObject(responStr.getData());
        if (responObject.containsKey("err_no") && "0".equals(responObject.get("err_no").toString())){
            AccessTokenVo tokenVo = responObject.get("data",AccessTokenVo.class);
            redisTemplate.opsForValue().set(Constant.DOUDIAN_ACCESS_TOKEN,tokenVo.getAccessToken(),tokenVo.getExpiresIn()-120, TimeUnit.SECONDS);
            redisTemplate.opsForValue().set(Constant.DOUDIAN_REFRESH_TOKEN,tokenVo.getRefreshToken(),tokenVo.getExpiresIn(), TimeUnit.SECONDS);
            return tokenVo.getAccessToken();
        }else{
            return null;
        }
    }

    /**
     * https://openapi-fxg.jinritemai.com/token/refresh?app_key=your_app_key&method=token.refresh&param_json={"grant_type":"refresh_token","refresh_token":"2ecd9731-537f-436f-84ea-ecf39e8646f8"}&timestamp=2021-07-02 16:35:13&v=2&sign=your_sign_here
     * @param refreshToken
     * @return
     */
    public String doudianRefreshToken(String shopId,String refreshToken ) throws IOException{
        Map<String, Object> mapToken = new HashMap<>();
        mapToken.put("refresh_token", refreshToken);
        mapToken.put("grant_type", "refresh_token");
        String responStr = send(shopId,"token.refresh",mapToken);
        JSONObject responObject = new JSONObject(responStr);
        if ("0".equals(responObject.get("err_no").toString())){
            AccessTokenVo tokenVo = responObject.get("data",AccessTokenVo.class);
            redisTemplate.opsForValue().set(Constant.DOUDIAN_ACCESS_TOKEN,tokenVo.getAccessToken(),tokenVo.getExpiresIn()-120, TimeUnit.SECONDS);
            redisTemplate.opsForValue().set(Constant.DOUDIAN_REFRESH_TOKEN,tokenVo.getRefreshToken(),tokenVo.getExpiresIn(), TimeUnit.SECONDS);
            return tokenVo.getAccessToken();
        }else{
            return null;
        }
    }
    /**
     * 卡券核销接口V2版本
     * https://openapi-fxg.jinritemai.com/coupons/verifyV2?app_key=your_appkey_here&method=coupons.verifyV2&access_token=your_accesstoken_here&param_json={}&timestamp=2018-06-19%2016:06:59&v=2&sign=your_sign_here
     * @param shopId
     * @param certNo
     * @return  {
     *   "data": {
     *   },
     *   "err_no": 0,
     *   "message": "success"
     * }
     */
    public R doudianCouponsVerifyV2(String shopId, String certNo)throws IOException{
        Map<String, Object> hashMap = new HashMap<>();
        hashMap.put("cert_no",certNo);
        String responStr = send(shopId,"coupons.verifyV2",hashMap);
        JSONObject responObject = new JSONObject(responStr);
        if ("0".equals(responObject.get("err_no").toString())){
            return R.ok();
        }else{
            return null;
        }
    }
    /**
     * 订单详情查询
     * https://openapi-fxg.jinritemai.com/order/orderDetail?app_key=your_appkey_here&method=order.orderDetail&access_token=your_accesstoken_here&param_json={}&timestamp=2018-06-19%2016:06:59&v=2&sign=your_sign_here
     */
    public R doudianOrderDetail(String shopId , String shopOrderId)throws IOException{
        HashMap<String, Object> map = new HashMap<>();
        map.put("shop_order_id",shopOrderId);
        String responStr = send(shopId, "order.orderDetail",map);
        JSONObject responObject = new JSONObject(responStr);
        if ("0".equals(responObject.get("err_no").toString())){
            return R.ok();
        }else{
            return null;
        }
    }

    /**
     * 订单列表
     * https://openapi-fxg.jinritemai.com/order/searchList?app_key=your_appkey_here&method=order.searchList&access_token=your_accesstoken_here&param_json={}&timestamp=2018-06-19%2016:06:59&v=2&sign=your_sign_here
     */
    public R doudianOrderList(String shopId ,Integer page ,Integer size,String startTime,String endTime )throws IOException{
        HashMap<String, Object> map = new HashMap<>();
        map.put("size",size);
        map.put("page",page);
        map.put("create_time_start",startTime);
        map.put("create_time_end",endTime);
        String responStr = send(shopId, "order.searchList",map );
        System.out.println(responStr);
        JSONObject responObject = new JSONObject(responStr);
        if ("0".equals(responObject.get("err_no").toString())){
            return R.ok();
        }else{
            return null;
        }
    }


    /**
     * 卡券列表，暂时无该能力
     * @param shopId
     * @param orderId
     * @return
     * @throws IOException
     */
    public R doudianCouponList(String shopId ,String orderId ,String certNo)throws IOException{
        HashMap<String, Object> map = new HashMap<>();
        if (StringUtils.isNotBlank(orderId))
            map.put("order_id",orderId);
        if (StringUtils.isNotBlank(certNo))
            map.put("cert_no",certNo);

        String responStr = send(shopId, "coupons.list",map );
        System.out.println(responStr);
        JSONObject responObject = new JSONObject(responStr);
        if ("0".equals(responObject.get("err_no").toString())){
            return R.ok();
        }else{
            return null;
        }
    }



}
